package BLC

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"math/big"
)

const (
	tarhetBit = 16
)

type ProofOfWork struct {
	block *Block		//当前要验证的区块
	target *big.Int		//大数据存储

}

func (proofOfWork *ProofOfWork) Run() ([]byte,int64) {
	// 1. 将Block的属性拼接成字节数组
	// 2. 生成hsh

	// 3. 判断hsh的有效性，满足条件的则结束
	nonce := 0
	var hashInt = big.NewInt(0)		//存储新生成的hash
	var hash [32]byte
	for true {
		dataBytes := proofOfWork.prepareData(nonce)
		hash = sha256.Sum256(dataBytes)
		//将hash存储到hashInt
		hashInt.SetBytes(hash[:])
		fmt.Printf("\r%x",hashInt)
		//判断hashInt是否小于Block里面的target
		if proofOfWork.target.Cmp(hashInt) == 1 {
			fmt.Println()
			break;
		}

		nonce ++
	}

	return nil,0
}

// 创建新的工作量证明对象
func NewProofOfWork(block *Block) *ProofOfWork {
	target := big.NewInt(1)
	target.Lsh(target,256-tarhetBit)
	fmt.Printf("%x\n",target)
	return &ProofOfWork{block,target}
}

func (pow *ProofOfWork) prepareData(nonce int) []byte {
	data := bytes.Join(
		[][]byte{
			pow.block.PrevBlockHash,
			pow.block.Data,
			IntToHex(int64(tarhetBit)),
			IntToHex(int64(nonce)),
			IntToHex(int64(pow.block.Height)),
		},
		[]byte{},)
	return data
}
